package cn.mw.cmdb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.mw.cmdb.entity.AssetsDiscoverInfo;
import cn.mw.cmdb.entity.MwCustomRuleInfo;
import cn.mw.cmdb.entity.MwCustomRuleInfoVo;
import cn.mw.cmdb.mongoMapper.AssetsScanResultMapper;
import cn.mw.cmdb.mongoMapper.MwCustomRuleMapper;
import cn.mw.cmdb.param.MwCustomRuleIdsParam;
import cn.mw.cmdb.task.AssetsDiscoveryRunManage;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.components.mongodb.entity.SearchParam;
import cn.mw.components.mongodb.tool.CriteriaWrapper;
import cn.mw.microMonitorCommon.api.common.MwTPServerService;
import cn.mw.microMonitorCommon.api.user.MwUserApi;
import cn.mw.microMonitorCommon.security.dto.MwUser;
import cn.mw.microMonitorCommon.util.DateUtils;
import cn.mw.microMonitorCommon.util.ModuleIDManager;
import cn.mw.microMonitorCommon.util.RedisUtils;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
public class MwCustomRuleServiceImpl extends ModelBaseServiceImpl<MwCustomRuleInfo, Object> {

    public static final String ID = "customRule";

    public static final String patternStr = "yyyy-MM-dd HH:mm:ss";

    protected static final Map<String, Integer> MONGO_SAVE_PROGRESS = new ConcurrentHashMap<>();

    private final CmdbServiceManage cmdbServiceManage;

    private final MwCustomRuleMapper customRuleMapper;

    private RedisUtils redisUtils;

    private final ModuleIDManager moduleIDManager;
    private final MwUserApi userApi;

    private AssetsScanResultMapper detailMapper;

    private AssetsDiscoveryRunManage runManage;

    private MwTPServerService mwTPServerService;

    public MwCustomRuleServiceImpl(CmdbServiceManage cmdbServiceManage, MwCustomRuleMapper customRuleMapper,
                                   ModuleIDManager moduleIDManager, MwUserApi mwUserApi, RedisUtils redisUtils, AssetsScanResultMapper detailMapper
            , AssetsDiscoveryRunManage runManage, MwTPServerService mwTPServerService) {
        this.cmdbServiceManage = cmdbServiceManage;
        this.customRuleMapper = customRuleMapper;
        this.moduleIDManager = moduleIDManager;
        this.userApi = mwUserApi;
        this.redisUtils = redisUtils;
        this.detailMapper = detailMapper;
        this.runManage = runManage;
        this.mwTPServerService = mwTPServerService;
    }

    @Override
    public MwCustomRuleInfo genObject() {
        return new MwCustomRuleInfo();
    }


    @Override
    Object doAdd(MwCustomRuleInfo param) throws Exception {
        CMDBTool.initCreateInfo(param);
        customRuleMapper.insert(param);
        return true;
    }

    @Override
    boolean doUpdate(MwCustomRuleInfo param) throws Exception {
        CMDBTool.initUpdateInfo(param);
        Query query = new Query(CriteriaWrapper.where(MwCustomRuleInfo::getId).is(param.getId()));
        Update update = CMDBTool.genMongoUpdate(param, null, null);
        CMDBTool.updateFirst(customRuleMapper, query, update);
        return true;
    }

    @Override
    boolean doRemove(MwCustomRuleInfo param) throws Exception {
        return false;
    }

    @Override
    Object doBatchAdd(Object params) throws Exception {
        return true;
    }

    @Override
    boolean doBatchUpdate(Object params) throws Exception {
        return false;
    }

    @Override
    public MwCustomRuleInfo doSelectById(Object id) throws Exception {
        MwCustomRuleInfo info = customRuleMapper.findById(id);
        return info;
    }

    public List<MwCustomRuleInfo> doSelectByIds(List<String> ids) throws Exception {
        Query query = new Query();
        Criteria criteria = CriteriaWrapper.where(AssetsDiscoverInfo::getId).in(ids);
        query.addCriteria(criteria);
        List<MwCustomRuleInfo> infos = customRuleMapper.find(query);
        return infos;
    }

    @Override
    List<MwCustomRuleInfo> doSelectList(Object param) throws Exception {
        SearchParam searchParam = (SearchParam) param;
        Criteria criteria = genCriteria(searchParam);
        if (Strings.isNullOrEmpty(searchParam.getSortName())) {
            searchParam.setSortName(CMDBTool.getFieldName(MwCustomRuleInfo::getCreateTime));
            searchParam.setSortOrder("DESC");
        }
        List<MwCustomRuleInfo> ruleInfos = CMDBTool.aggregateAuthorizedList(MwCustomRuleInfo.class, customRuleMapper, criteria, searchParam);
        return ruleInfos;
    }

    @Override
    boolean doBatchRemove(Object params) throws Exception {
        if (params != null && params instanceof MwCustomRuleIdsParam) {
            MwCustomRuleIdsParam idsParam = (MwCustomRuleIdsParam) params;
            CMDBTool.remove(customRuleMapper, idsParam.getIds(), MwCustomRuleInfo.class, true);
            return true;
        }
        return false;
    }

    public List<String> getRuleNamesByIds(List<String> ids) throws Exception {
        List<MwCustomRuleInfo> infoList = doSelectByIds(ids);
        infoList = Optional.ofNullable(infoList).orElse(new ArrayList<>());
        return infoList.stream().map(MwCustomRuleInfo::getRuleName).toList();
    }



  public List<MwCustomRuleInfoVo> dataListConvert(List<MwCustomRuleInfo> ruleInfos) throws Exception {
        List<MwCustomRuleInfoVo> newList = new ArrayList<>();
        Set<Long> userIdSet = ruleInfos.stream().flatMap(s -> Stream.of(s.getCreater(), s.getModifier())).filter(value -> value != null && value != 0l).collect(Collectors.toSet());
        List<Long> userIdList = new ArrayList<>(userIdSet);
        Map<String, String> userIdMap = null;
        if (CollectionUtil.isNotEmpty(userIdList)) {
            List<MwUser> usersByUserIds = userApi.getUsersByUserIds(userIdList);
            if (CollectionUtil.isNotEmpty(usersByUserIds)) {
                userIdMap = usersByUserIds.stream().collect(Collectors.toMap(k -> String.valueOf(k.getId()), MwUser::getNickName, (o1, o2) -> o1));
            }
        }
        for (MwCustomRuleInfo ruleInfo : ruleInfos) {
            MwCustomRuleInfoVo infoVo = new MwCustomRuleInfoVo();
            BeanUtil.copyProperties(ruleInfo, infoVo);

            if (userIdMap != null && userIdMap.containsKey(infoVo.getCreater())) {
                infoVo.setCreaterName(userIdMap.get(infoVo.getCreater()));
            }
            if (userIdMap != null && userIdMap.containsKey(infoVo.getModifier())) {
                infoVo.setModifierName(userIdMap.get(infoVo.getModifier()));
            }
            infoVo.setCreateTime(DateUtils.format(ruleInfo.getCreateTime(),patternStr) );
            infoVo.setModificationTime(DateUtils.format(ruleInfo.getModificationTime(),patternStr));
            //TODO 设置关联的资产发现数据
            infoVo.setAssetsScanInfos(null);
            newList.add(infoVo);
        }
        return newList;
    }

}
